package com.quectel.core.module.scheduling.service.impl.mongo;

import com.quectel.constant.global.SystemConstants;
import com.quectel.core.constants.MongoCollectionConstants;
import com.quectel.core.module.MongoAuthComponent;
import com.quectel.core.module.dept.dto.DeptDto;
import com.quectel.core.module.dept.dto.DeptPersonDto;
import com.quectel.core.module.dept.entity.DeptEntity;
import com.quectel.core.module.dept.entity.DeptPersonEntity;
import com.quectel.core.module.scheduling.dto.SchedulingAttendanceGroupDto;
import com.quectel.core.module.scheduling.dto.SchedulingTimeConfigDto;
import com.quectel.core.module.scheduling.dto.mongo.MongoOriginalCheckRecordDto;
import com.quectel.core.module.scheduling.entity.SchedulingAttendanceGroupEntity;
import com.quectel.core.module.scheduling.entity.SchedulingTimeConfigEntity;
import com.quectel.core.module.scheduling.entity.mongo.MongoOriginalCheckRecordModel;
import com.quectel.core.module.scheduling.service.mongo.MongoOriginalCheckRecordService;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.Request;
import com.quectel.util.kit.Snowflake;
import com.quectel.util.mongo.MongodbUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@DubboService
public class MongoOriginalCheckRecordServiceImpl implements MongoOriginalCheckRecordService {
    @Autowired
    private MongoAuthComponent mongoAuthComponent;
    @Autowired
    private VillageService villageService;

    private Criteria sqlWhere(Map<String, Object> params) {
        Request request = Request.configParams(params);


        Criteria authByAllQuery = mongoAuthComponent.buildAuthByRegionOrVillageQuery(params, "tenantId", "villageId");

        Criteria otherFieldQuery = new Criteria();

        Date startTime = request.getDate("startTime", DateUtils.FormatType.COMMON.getType());
        Date endTime = request.getDate("endTime", DateUtils.FormatType.COMMON.getType());

        if (startTime != null && endTime != null) {
            otherFieldQuery.and("checkTime").gte(startTime).lte(endTime);
        }
        Long personId = request.getLong("personId");
        if (personId != null) {
            otherFieldQuery.and("personId").is(personId);
        }
        Long dailyId = request.getLong("dailyId");
        if (dailyId != null) {
            otherFieldQuery.and("dailyId").is(dailyId);
        }
        return new Criteria().andOperator(authByAllQuery, otherFieldQuery);
    }

    @Override
    public int queryTotal(Map<String, Object> params) {

        return (int) MongodbUtils.count(new Query(sqlWhere(params)), MongoCollectionConstants.ATTENDANCE_ORIGINAL_CHECK_RECORD);
    }

    @Override
    public List<MongoOriginalCheckRecordDto> queryList(Map<String, Object> params) {
        Request request = Request.configParams(params);
        return
                MongodbUtils.page(
                        new Query(sqlWhere(params)),
                        request.getPageNo() - 1,
                        request.getPageSize(),
                        Sort.by(Sort.Direction.DESC, SystemConstants.MONGO_ENTITY_ID_FLAG),
                        MongoOriginalCheckRecordModel.class,
                        MongoCollectionConstants.ATTENDANCE_ORIGINAL_CHECK_RECORD
                ).stream().map(model -> {
                    MongoOriginalCheckRecordDto mongoOriginalCheckRecordDto = CopyUtils.copyObj(model, MongoOriginalCheckRecordDto.class);
                    mongoOriginalCheckRecordDto.setDeptPerson(CopyUtils.copyObj(model.getDeptPerson(), DeptPersonDto.class));
                    mongoOriginalCheckRecordDto.setDept(CopyUtils.copyObj(model.getDept(), DeptDto.class));
                    mongoOriginalCheckRecordDto.setSchedulingAttendanceGroup(CopyUtils.copyObj(model.getSchedulingAttendanceGroup(), SchedulingAttendanceGroupDto.class));
                    mongoOriginalCheckRecordDto.setTimes(CopyUtils.copyList(model.getTimes(), SchedulingTimeConfigDto.class));

                    VillageDto villageDto = villageService.selectCacheById(model.getVillageId());
                    mongoOriginalCheckRecordDto.setVillage(villageDto);
                    return mongoOriginalCheckRecordDto;
                }).collect(Collectors.toList());
    }

    @Override
    public Long save(MongoOriginalCheckRecordDto mongoOriginalCheckRecordDto) {
        MongoOriginalCheckRecordModel model = CopyUtils.copyObj(mongoOriginalCheckRecordDto, MongoOriginalCheckRecordModel.class);
        model.setDeptPerson(CopyUtils.copyObj(mongoOriginalCheckRecordDto.getDeptPerson(), DeptPersonEntity.class));
        model.setDept(CopyUtils.copyObj(mongoOriginalCheckRecordDto.getDept(), DeptEntity.class));
        model.setSchedulingAttendanceGroup(CopyUtils.copyObj(mongoOriginalCheckRecordDto.getSchedulingAttendanceGroup(), SchedulingAttendanceGroupEntity.class));
        model.setTimes(CopyUtils.copyList(mongoOriginalCheckRecordDto.getTimes(), SchedulingTimeConfigEntity.class));

        model.setId(Snowflake.nextId());
        MongodbUtils.add(model, MongoCollectionConstants.ATTENDANCE_ORIGINAL_CHECK_RECORD);
        return model.getId();
    }
}
